package es.deusto.programacionIV.calculator.console;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

import es.deusto.programacionIV.calculator.model.Operation;
import es.deusto.programacionIV.calculator.model.OperationType;
import es.deusto.programacionIV.utils.FileUtils;
import es.deusto.programacionIV.utils.JarUtils;
import es.deusto.programacionIV.utils.SystemInUtils;

/**
 * This class represents the main program of a calculator.
 * The sixth version of the calculator (v0.6) is the sixth iteration to show that using multiple jars is a great 
 * opportunity to create a completely independent/modular solution.
 * 
 * @author Iker Jamardo Zugaza
 *
 */
public class Main 
{
	public static final String OPERATION_TYPES_JARS_PATH_CONFIGURATION_FILE_PATH = "OperationTypeJarsPathConfiguration.txt";
	public static final String OPERATION_TYPES_CONFIGURATION_FILE_PATH = "OperationTypesConfiguration.txt";
	
	private static void showMenu(OperationType[] operationTypes)
	{	
		// Show the menu.
		System.out.println("Calculator v0.6");
		for (int i = 0; i < operationTypes.length; i++)
		{
			System.out.println((i + 1) + ".- " + operationTypes[i]);
		}
		System.out.println((operationTypes.length + 1) + ".- List of all done operations");
		System.out.println((operationTypes.length + 2) + ".- Refresh the operation types");
		System.out.println((operationTypes.length + 3) + ".- Exit");
	}
	
	public static void main(String[] args) throws Exception 
	{
		// Read the lines at the jars path configuration txt file
		String[] lines = FileUtils.readLinesFromTXTFile(OPERATION_TYPES_JARS_PATH_CONFIGURATION_FILE_PATH);
		String jarsDirectoryPath = lines[0];
		
		// Create the instances of OperationTypes.
		Collection<OperationType> operationTypes = JarUtils.instantiateObjectsFromJarFilesWithClassNameTXTFile(jarsDirectoryPath, OPERATION_TYPES_CONFIGURATION_FILE_PATH);
		OperationType[] operationTypesArray = new OperationType[operationTypes.size()];
		operationTypesArray = operationTypes.toArray(operationTypesArray);
		
		ArrayList<Operation> operations = new ArrayList<Operation>();
		try
		{
			int option = 0;
			int exitOption = 0;
			do
			{
				exitOption = operationTypesArray.length + 3;
				showMenu(operationTypesArray);
				option = SystemInUtils.readInt(1, operationTypesArray.length + 3, "Option: ");
				// If the option is a integer between 1 and 4, it's an operation.
				if (option >= 1 && option <= (operationTypesArray.length))
				{
					// Create the operation with the specified type and query for the operands and set them.
					Operation operation = operationTypesArray[option - 1].createOperation();
					// Use a loop to query for the operands.
					for (int i = 1; i < 3; i++)
					{
						boolean correct = false;
						do
						{
							try
							{
								float operand = SystemInUtils.readFloat("Introduce the operand " + i + ": ");
								switch(i)
								{
								case 1:
									operation.setOperand1(operand);
									break;
								case 2:
									operation.setOperand2(operand);
									break;
								}
								correct = true;
							}
							catch(IllegalArgumentException e)
							{
								System.err.println("ERROR: " + e.getMessage());
							}
						}
						while(!correct);
					}
					
					System.out.println(operation);
					
					operations.add(operation);
				}
				else if (option == operationTypesArray.length + 1)
				{
					System.out.println("Listing done operations:");
					for (Operation operation: operations)
					{
						System.out.println(operation);
					}
				}
				else if (option == operationTypesArray.length + 2)
				{
					System.out.println("Refreshing the operation types...");
					operationTypes = JarUtils.instantiateObjectsFromJarFilesWithClassNameTXTFile(jarsDirectoryPath, OPERATION_TYPES_CONFIGURATION_FILE_PATH);
				}
			}
			while(option != exitOption);
		}
		catch(IOException e)
		{
			System.err.println("ERROR: There has been a severe hadware failure when trying to communicate with the keyboard.");
		}
	}
}
